home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Appls / dpv / dpvfonts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-29  |  11.9 KB  |  420 lines  |  [TEXT/????]

  1. /* dpv -- ditroff previewer.  Font translation. */
  2.  
  3. #include "dpv.h"
  4. #include "dpvmachine.h"
  5. #include "dpvoutput.h"
  6.  
  7. /* Font translation table, to map ditroff font names to font names
  8.    STDWIN (really the underlying window system) understands.
  9.    This information should really be read from a configuration file.
  10.    For now, we know to map some ditroff names for Harris and PostScript
  11.    fonts to more or less equivalent X11 and Mac fonts.
  12.    (The X fonts used are to be found in the Andrew distribution).
  13.    Because the current font scheme in STDWIN for X doesn't know about
  14.    wsetsize and wsetbold c.s., the translation process is different
  15.    for X than for the Macintosh. */
  16.  
  17. #define NSIZES 10
  18.  
  19. #define R    0
  20. #define B    1
  21. #define I    2
  22. #define BI    3
  23.  
  24. static struct _translate {
  25.     char *harname;
  26.     char *xname;
  27.     int style;
  28.     int sizes[NSIZES+1];
  29. } default_translate[]= {
  30. #ifdef macintosh
  31.     {"R",    "Times",    R},
  32.     {"I",    "Times",    I},
  33.     {"B",    "Times",    B},
  34.     {"BI",    "Times",    BI},
  35.     
  36.     {"H",    "Helvetica",    R},
  37.     {"HO",    "Helvetica",    I},
  38.     {"HB",    "Helvetica",    B},
  39.     {"HD",    "Helvetica",    BI},
  40.     
  41.     {"C",    "Courier",    R},
  42.     {"CO",    "Courier",    I},
  43.     {"CB",    "Courier",    B},
  44.     {"CD",    "Courier",    BI},
  45.     
  46.     {"lp",    "Courier",    R},
  47.     
  48.     {"Vl",    "Helvetica",    R},
  49.     {"vl",    "Helvetica",    R},
  50.     {"V",    "Helvetica",    R},
  51.     {"v",    "Helvetica",    R},
  52.     
  53.     /* Font used by funny character translation */
  54.     
  55.     {"Symbol", "Symbol",    R},
  56. #else
  57. #ifdef X11R2
  58.     /* X11 Release 2, using fonts from Andrew */
  59.     
  60.     /* PostScript font names */
  61.     
  62.     {"R",    "times%d",    R, 8, 10, 12, 16, 22, 0},
  63.     {"I",    "times%di",    R, 8, 10, 12, 16, 22, 0},
  64.     {"B",    "times%db",    R, 8, 10, 12, 16, 22, 0},
  65.     {"BI",    "times%dbi",    R, 8, 10, 12, 16, 22, 0},
  66.     
  67.     {"H",    "helvetica%d",    R, 8, 10, 12, 16, 22, 0},
  68.     {"HO",    "helvetica%di",    R, 8, 10, 12, 16, 22, 0},
  69.     {"HB",    "helvetica%db",    R, 8, 10, 12, 16, 22, 0},
  70.     {"HD",    "helvetica%dbi",R, 8, 10, 12, 16, 22, 0},
  71.     
  72.     {"C",    "courier%df",    R, 8, 10, 12, 16, 22, 0},    
  73.     {"CO",    "courier%dif",    R, 8, 10, 12, 16, 22, 0},
  74.     {"CB",    "courier%dbf",    R, 8, 10, 12, 16, 22, 0},
  75.     {"CD",    "courier%dbif", R, 8, 10, 12, 16, 22, 0},
  76.     
  77.     /* CWI Harris font names (also R, I, B, BI) */
  78.     
  79.     /* Vega light, Vega, Vega medium (Helvetica look-alike) */
  80.     {"Vl",    "helvetica%d",    R, 8, 10, 12, 16, 22, 0},
  81.     {"vl",    "helvetica%di",    R, 8, 10, 12, 16, 22, 0},
  82.     {"V",    "helvetica%d",    R, 8, 10, 12, 16, 22, 0},
  83.     {"v",    "helvetica%di",    R, 8, 10, 12, 16, 22, 0},
  84.     {"Vm",    "helvetica%db",    R, 8, 10, 12, 16, 22, 0,},
  85.     {"vm",    "helvetica%dbi",R, 8, 10, 12, 16, 22, 0,},
  86.     
  87.     /* Baskerville (see also small caps) */
  88.     {"br",    "times%d",    R, 8, 10, 12, 16, 22, 0,},
  89.     {"bi",    "times%di",    R, 8, 10, 12, 16, 22, 0,},
  90.     {"bb",    "times%db",    R, 8, 10, 12, 16, 22, 0,},
  91.     {"bI",    "times%dbi",    R, 8, 10, 12, 16, 22, 0,},
  92.     
  93.     /* Century Schoolbook */
  94.     {"cr",    "times%d",    R, 8, 10, 12, 16, 22, 0,},
  95.     {"ci",    "times%di",    R, 8, 10, 12, 16, 22, 0,},
  96.     {"cb",    "times%db",    R, 8, 10, 12, 16, 22, 0,},
  97.     {"cI",    "times%dbi",    R, 8, 10, 12, 16, 22, 0,},
  98.     
  99.     /* Laurel */
  100.     {"lr",    "times%d",    R, 8, 10, 12, 16, 22, 0,},
  101.     {"li",    "times%di",    R, 8, 10, 12, 16, 22, 0,},
  102.     {"lb",    "times%db",    R, 8, 10, 12, 16, 22, 0,},
  103.     {"lI",    "times%dbi",    R, 8, 10, 12, 16, 22, 0,},
  104.     
  105.     /* Funny fonts mapped to Helvetica, at least they differ from Times */
  106.     {"G3",    "helvetica%d",    R, 8, 10, 12, 16, 22, 0,}, /* German no 3 */
  107.     {"fs",    "helvetica%d",    R, 8, 10, 12, 16, 22, 0,}, /* French Script */
  108.     {"RS",    "helvetica%di",    R, 8, 10, 12, 16, 22, 0,}, /* Rose Script */
  109.     {"SO",    "helvetica%db",    R, 8, 10, 12, 16, 22, 0,}, /* Scitype Open */
  110.     
  111.     /* OCR-B (line printer font) */
  112.     {"lp",    "courier%dbf",    R, 8, 10, 12, 0},
  113.     
  114.     /* Small caps fonts mapped to normal fonts */
  115.     {"Rs",    "times%d",    R, 8, 10, 12, 16, 22, 0,}, /* Times */
  116.     {"Bs",    "times%db",    R, 8, 10, 12, 16, 22, 0,}, /* Times bold */
  117.     {"bs",    "times%d",    R, 8, 10, 12, 16, 22, 0,}, /* Baskerville */
  118.     {"bS",    "times%db",    R, 8, 10, 12, 16, 22, 0,}, /* Baskerv. bold */
  119.     
  120.     /* Fonts used by funny character translation */
  121.     
  122.     {"symbol", "symbol%d",    R, 8, 10, 12, 16, 22, 0},
  123.     {"symbola","symbola%d", R, 8, 10, 12, 16, 22, 0},
  124. #else /* ! X11R3 */
  125.     /* X11 Release 3 fonts */
  126.     /* Also works for Release 4 */
  127.     
  128.     /* PostScript font names */
  129.     
  130.     {"R",    "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  131.     {"I",    "-*-times-medium-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  132.     {"B",    "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  133.     {"BI",    "-*-times-bold-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  134.     
  135.     {"H",    "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  136.     {"HO",    "-*-helvetica-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  137.     {"HB",    "-*-helvetica-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  138.     {"HD",    "-*-helvetica-bold-o-*--%d-*",R, 8, 10, 12, 14, 18, 24, 0},
  139.     
  140.     {"C",    "-*-courier-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},    
  141.     {"CO",    "-*-courier-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  142.     {"CB",    "-*-courier-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  143.     {"CD",    "-*-courier-bold-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  144.     
  145.     /* CW is a common alias for C */
  146.     {"CW",    "-*-courier-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},    
  147.     
  148.     /* CWI Harris font names (also R, I, B, BI) */
  149.     
  150.     /* Vega light, Vega, Vega medium (Helvetica look-alike) */
  151.     {"Vl",    "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  152.     {"vl",    "-*-helvetica-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  153.     {"V",    "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  154.     {"v",    "-*-helvetica-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  155.     {"Vm",    "-*-helvetica-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  156.     {"vm",    "-*-helvetica-bold-o-*--%d-*",R, 8, 10, 12, 14, 18, 24, 0,},
  157.     
  158.     /* Baskerville (see also small caps) */
  159.     {"br",    "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  160.     {"bi",    "-*-times-medium-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  161.     {"bb",    "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  162.     {"bI",    "-*-times-bold-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  163.     
  164.     /* Century Schoolbook */
  165.     {"cr",    "-*-new century schoolbook-medium-r-*--%d-*",
  166.     R, 8, 10, 12, 14, 18, 24, 0,},
  167.     {"ci",    "-*-new century schoolbook-medium-i-*--%d-*",
  168.     R, 8, 10, 12, 14, 18, 24, 0,},
  169.     {"cb",    "-*-new century schoolbook-bold-r-*--%d-*",
  170.     R, 8, 10, 12, 14, 18, 24, 0,},
  171.     {"cI",    "-*-new century schoolbook-bold-i-*--%d-*",
  172.     R, 8, 10, 12, 14, 18, 24, 0,},
  173.     
  174.     /* Laurel */
  175.     {"lr",    "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  176.     {"li",    "-*-times-medium-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  177.     {"lb",    "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  178.     {"lI",    "-*-times-bold-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  179.     
  180.     /* Funny fonts mapped to Helvetica, at least they differ from Times */
  181.     {"G3",    "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  182.     /* German no 3 */
  183.     {"fs",    "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  184.     /* French Script */
  185.     {"RS",    "-*-helvetica-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  186.     /* Rose Script */
  187.     {"SO",    "-*-helvetica-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  188.     /* Scitype Open */
  189.     
  190.     /* OCR-B (line printer font) */
  191.     {"lp",    "-*-courier-bold-r-*--%d-*", R, 8, 10, 12, 0},
  192.     
  193.     /* Small caps fonts mapped to normal fonts */
  194.     {"Rs",    "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  195.     /* Times */
  196.     {"Bs",    "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  197.     /* Times bold */
  198.     {"bs",    "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  199.     /* Baskerville */
  200.     {"bS",    "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
  201.     /* Baskerville bold */
  202.     
  203.     /* Fonts used by funny character translation */
  204.     
  205.     {"r3symbol", "*-*-symbol-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
  206. #endif /* ! X11R2 */
  207. #endif /* ! macintosh */
  208.     
  209.     {NULL,    NULL}
  210. };
  211.  
  212. static struct _translate *translate = default_translate;
  213.  
  214. /* Tell STDWIN to use the desired font and size.
  215.    Call at start of page and after each font or size change. */
  216.  
  217. usefont()
  218. {
  219.     char *fontname;
  220.     
  221.     if (showpage != ipage)
  222.         return;
  223.     
  224.     fontname= fonts.name[font];
  225.     if (fontname != NULL)
  226.         fonthack(fontname);
  227.     /* Else, font not loaded -- assume in initialization phase */
  228.     baseline= wbaseline();
  229.     lineheight= wlineheight();
  230.     recheck();
  231. }
  232.  
  233. fonthack(fontname)
  234.     char *fontname;
  235. {
  236.     int i;
  237.     int havesize;
  238.     char *harname;
  239.     char buf[256];
  240.     struct _translate *t;
  241.     
  242.     for (t= translate; t->harname != NULL; ++t) {
  243.         if (strcmp(t->harname, fontname) == 0)
  244.             break;
  245.     }
  246.     if (t->harname == NULL) {
  247.         fontwarning(fontname);
  248.     }
  249.     else {
  250. #ifdef macintosh
  251.         wsetfont(t->xname);
  252.         wsetsize(size);
  253.         wsetplain();
  254.         switch (t->style) {
  255.         case I: wsetitalic(); break;
  256.         case B: wsetbold(); break;
  257.         case BI: wsetbolditalic(); break;
  258.         }
  259. #else
  260.         havesize= size;
  261.         for (i= 0; ; ++i) {
  262.             if (t->sizes[i] >= havesize || t->sizes[i+1] == 0) {
  263.                 havesize= t->sizes[i];
  264.                 break;
  265.             }
  266.         }
  267.         sprintf(buf, t->xname, havesize);
  268.         wsetfont(buf);
  269. #endif
  270.     }
  271. }
  272.  
  273. /* Issue a warning.
  274.    Avoid warning many times in a row about the same font. */
  275.  
  276. fontwarning(fontname)
  277.     char *fontname;
  278. {
  279.     static char lastwarning[200];
  280.     char buf[256];
  281.     
  282.     if (strncmp(lastwarning, fontname, sizeof lastwarning) != 0) {
  283.         strncpy(lastwarning, fontname, sizeof lastwarning);
  284.         sprintf(buf, "mapping for font %s unknown", fontname);
  285.         error(WARNING, buf);
  286.     }
  287. }
  288.  
  289. /* Get a token */
  290.  
  291. static char *
  292. gettok(pp)
  293.     char **pp;
  294. {
  295.     char *p = *pp;
  296.     char *start;
  297.     char c;
  298.     
  299.     while (isspace(c = *p++)) /* Skip to start of token */
  300.         ;
  301.     if (c == '\0' || c == '\n' || c == '#') {
  302.         if (dbg > 2)
  303.             if (c == '#')
  304.                 fprintf(stderr, "next token is comment\n");
  305.             else if (c == '\n')
  306.                 fprintf(stderr, "next token is newline\n");
  307.             else
  308.                 fprintf(stderr, "next token is EOS\n");
  309.         return NULL; /* End of line of comment */
  310.     }
  311.     start = p-1; /* Remember start of token */
  312.     while (!isspace(c = *p++) && c != '\0') /* Skip to end of token */
  313.         ;
  314.     if (c == '\0')
  315.         p--;
  316.     else
  317.         p[-1] = '\0'; /* Zero-terminate token */
  318.     *pp = p; /* Start point for next token */
  319.     if (dbg > 2)
  320.         fprintf(stderr, "next token: %s\n", start);
  321.     return start;
  322. }
  323.  
  324. static void
  325. addtrans(pnt, pt, harname, xname, style, sizes)
  326.     int *pnt;
  327.     struct _translate **pt;
  328.     char *harname;
  329.     char *xname;
  330.     int style;
  331.     int sizes[];
  332. {
  333.     int i = (*pnt)++;
  334.     struct _translate *t = *pt;
  335.     
  336.     if (i == 0)
  337.         t = (struct _translate *) malloc(sizeof(struct _translate));
  338.     else
  339.         t = (struct _translate *)
  340.             realloc((char *)t, sizeof(struct _translate) * *pnt);
  341.     if (t == NULL)
  342.         error(FATAL, "not enough memory for font translations");
  343.     *pt = t;
  344.     t += i;
  345.     t->harname = strdup(harname);
  346.     t->xname = strdup(xname);
  347.     t->style = style;
  348.     for (i = 0; i <= NSIZES; i++)
  349.         t->sizes[i] = sizes[i];
  350. }
  351.  
  352. /* Read a file of alternative font translations. */
  353.  
  354. readtrans(filename)
  355.     char *filename;
  356. {
  357.     struct _translate *t;
  358.     int nt;
  359.     FILE *fp;
  360.     int line;
  361.     char buf[1000];
  362.     char *p;
  363.     char *harname;
  364.     char *xname;
  365.     char *sizetemp;
  366.     int sizes[NSIZES+1];
  367.     static int defsizes[NSIZES+1] = {8, 10, 12, 14, 18, 24, 0};
  368.     int nsizes;
  369.     
  370.     fp = fopen(filename, "r");
  371.     if (fp == NULL)
  372.         error(FATAL, "can't find font translations file %s", filename);
  373.     if (dbg > 0)
  374.         fprintf(stderr, "reading translations from %s\n", filename);
  375.     t = NULL;
  376.     nt = 0;
  377.     line = 0;
  378.     while (fgets(buf, sizeof buf, fp) != NULL) {
  379.         line++;
  380.         if (dbg > 1)
  381.             fprintf(stderr, "line %d: %s\n", line, buf);
  382.         p = buf;
  383.         harname = gettok(&p);
  384.         if (harname == NULL)
  385.             continue; /* Blank line or comment */
  386.         xname = gettok(&p);
  387.         if (xname == NULL) {
  388.             error(WARNING, "%s(%d): incomplete line (only '%s')",
  389.                         filename, line, harname);
  390.             continue;
  391.         }
  392.         /* Style is always R */
  393.         nsizes = 0;
  394.         while (nsizes < NSIZES && (sizetemp = gettok(&p)) != NULL) {
  395.             sizes[nsizes] = atoi(sizetemp);
  396.             if (sizes[nsizes] <= 0 ||
  397.                     nsizes > 0 &&
  398.                     sizes[nsizes] <= sizes[nsizes-1]) {
  399.                 error(WARNING,
  400.                     "%s(%d): bad or non-increasing size '%s'",
  401.                     filename, line, sizetemp);
  402.             }
  403.             else
  404.                 nsizes++;
  405.         }
  406.         if (nsizes > 0)
  407.             while (nsizes <= NSIZES)
  408.                 sizes[nsizes++] = 0;
  409.         addtrans(&nt, &t, harname, xname, R,
  410.             nsizes == 0 ? defsizes : sizes);
  411.     }
  412.     if (dbg > 0)
  413.         fprintf(stderr, "done reading translations.\n");
  414.     fclose(fp);
  415.     if (nt == 0)
  416.         error(FATAL, "%s: no valid font translations", filename);
  417.     addtrans(&nt, &t, (char *)NULL, (char *)NULL, R, defsizes);
  418.     translate = t;
  419. }
  420.